package com.butang;


import java.sql.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;

/**
 * @Author weizs
 * @Create 2023/6/7 16:13
 * @Version 1.0
 */
public class NewScada {



    //十六位二进制最大数值
    static int HexBinary_Max = 65535;
    static long DoubleHexBinary_Max = 4294967295L;
    public static void main(String[] args) {
        try {
            //加载驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            Connection conn=  DriverManager.getConnection("jdbc:mysql://localhost:3306/scada","root","root");
            PreparedStatement pstmt= conn.prepareStatement("select * from meta_tag");
            Statement statement = conn.createStatement();
            PreparedStatement preparedStatement = null;


            String updateSql="update meta_tag_data_analysis  set TimeStamp= ?,TagValue= ? where TagID=?";
            preparedStatement = conn.prepareStatement(updateSql);

            long start = System.currentTimeMillis();
            String sql=null;
            ResultSet rs=null;


            System.out.println("------------------------开始解析:");
            sql="select a.TagID,a.Address,a.conf,b.TagValue from meta_tag a inner join meta_tag_real_data b on a.Address=b.Address";
            rs = statement.executeQuery(sql);
            while(rs.next()) {
                int TagID = rs.getInt("TagID");
                long TagValue = rs.getLong("TagValue");
                int conf = rs.getInt("conf");
                String Address = rs.getString("Address");
                // System.out.println(TagID+","+miniMum+","+maxiMum+","+TagValue+","+description+","+Address+","+TagName);
                String Value = "0";
                String str = null;
                String two = null;
                float value1 = 0;





                //对于conf进行判断
                int miniMum = conf % 10 % 10;
                int maxiMum = conf % 10 / 10;
                int description = conf / 100;

                //进行判断，是否需要进行处理

                if (conf % 10 != 10) {
                    if (miniMum == 1) { //需要符号处理
                        if (maxiMum != 1) { //需要精度处理
                            //16位
                            //这里需要 有16位符号转无符号，且进行精度处理
                            if (description == 2) { //32位
                                //这里需要 有32位符号转无符号，且进行精度处理
                                Value = String.valueOf((NewScadaCat.doubleUnsignedToSigned(TagValue)) / (Math.pow(10, (maxiMum ))));
                            } else {//16位
                                //这里需要 有16位符号转无符号，且进行精度处理
                                Value = String.valueOf((NewScadaCat.unsignedToSigned(TagValue)) / (Math.pow(10, (maxiMum ))));
                            }

                        } else { // 需要符号处理，不需要精度处理
                            if (description == 2) { //32位
                                //这里需要 有32位符号转无符号
                                Value = String.valueOf(NewScadaCat.doubleUnsignedToSigned(TagValue));
                            } else {//16位
                                //这里需要 有16位符号转无符号，且进行精度处理
                                Value = String.valueOf(NewScadaCat.unsignedToSigned(TagValue));
                            }
                        }
                    } else { //不需符号处理
                        if (maxiMum != 1) { //需要精度处理
                            Value = String.valueOf(TagValue / (Math.pow(10, (maxiMum ))));
                        }
                    }
                }


                //取出Address下标进行判断
                int length = Address.length();
                if (length >= 3) {
                    str = Address.substring(length - 3, length);
                    //System.out.println("字符串后三位："+str);
                }
                two = Address.substring(2, 3);
                //System.out.println("字符串第二位："+two);

                //系统故障状态和定日镜运行状态转换为16位二进制
                if (two.equals("3") && (str.equals("001") || str.equals("002"))) {
                    Value = NewScadaCat.decimalToBinary(TagValue);
                }

                //数据量大时，localdatetime效率更高
                LocalDateTime localDateTime = LocalDateTime.now();
                DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd :hh:mm:ss");
                String TimeStamp = localDateTime.format(dateFormat);

                preparedStatement.setString(1, TimeStamp);
                preparedStatement.setString(2, Value);
                preparedStatement.setInt(3, TagID);


                //preparedStatement.executeUpdate();

                //把data存储到容器中，然后一次性插入
                preparedStatement.addBatch();

                System.out.println(preparedStatement);
            }

            int[] temp = preparedStatement.executeBatch();
            System.out.println(Arrays.toString(temp));

            System.out.println("耗时:"+(System.currentTimeMillis() - start)+"ms");
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }
    }

    //Long.MAX_VALUE

    //十进制转换为十六位二进制并自动补齐
    public static String decimalToBinary(long n) {

        if (n < 0 || n >  HexBinary_Max) {
            throw new IllegalArgumentException("The input number must be between 0 and 65535.");
        }
        String binary = Long.toBinaryString(n);
        while (binary.length() < 16) {
            binary = "0" + binary;
        }
        return binary;
    }

    //十进制转换为三十二位二进制并自动补齐
    public static String decimalToBinary1(long n) {

        if (n < 0 || n >  DoubleHexBinary_Max) {
            throw new IllegalArgumentException("The input number must be between 0 and 65535.");
        }
        String binary = Long.toBinaryString(n);
        while (binary.length() < 32) {
            binary = "0" + binary;
        }
        return binary;
    }


    //无符号32位无符号转换为有符号
    public static long doubleUnsignedToSigned(long unsigned) {
        if (unsigned <= 2147483647) {
            return unsigned;
        } else {
            return -(DoubleHexBinary_Max + 1 - unsigned);
        }
    }

    //无符号十六位十进制转换为有符号十进制

    public static long unsignedToSigned(long unsigned) {
        if (unsigned <= 65535/2) {
            return unsigned;
        } else {
            return -(HexBinary_Max + 1 - unsigned);
        }
    }
}